System Instruction
System Instruction指的是跟系統息息相關的指令,例如前面有敘述過的CSR指令,又或者是今天要介紹的ecall、ebreak、wfi、mret、fence等指令。而這些指令的共同點在於說[6:0]的值為0x73,也就是7'b1110011。
今天會簡單介紹system指令的物理意義,但實作的部分由於身體狀況欠佳的原因可能要先欠著Q Q,會在後續補上。
ebreak/ecall指的都是用來跟上層系統溝通用的指令,ebreak專指break point,ecall則是通常用來處理system call,甚麼意思呢。
一般的RISC-V可以分成User mode, Supervisor mode和 Machine mode三者,而有一些指令、CSR位置是只有比較高層級的mode下才能夠做操作,例如說像待會會介紹到的mret,就是專門在machine mode底下才能使用的例子,而也因此會有例如sret等不同階級下的不同指令。
而要說明ecall和ebreak,我們要先介紹下面這張圖。
這張圖概括了RISC-V裡面會遇到的中斷,包含interrupt以及exception。而exception的部分有breakpoint, ecall from U-mode, ecall from S-mode, ecall from M-mode等。而ecall會讓我們呼叫能夠幫我們處理我這個層級不能處理的事情的人,例如說如前面所示,可以分成ecall from U-mode, ecall from S-mode, ecall from M-mode等不同的狀況,就可以跳到對應的程式碼片段 (trap-handler)去執行程式,而跳過去之後的權限內容也會有所變化。同理,ebreak也會跳去breakpoint斷進行處理(通常由debugger呼叫)。
舉例來說,我們簡單寫一個HelloWorld的時候,對於user code通常不知道系統上的硬體配置,一般來說是不會清楚要怎麼把值輸出到terminal上的,這時候就需要OS的幫助,因此如果我們觀察objdump時,可以觀察到printf最後會走到ecall,而ecall內os會根據呼叫ecall前設定的位置去將要printf的值讀回來,並printf到螢幕上,我們將來可以利用這點來進行輸入輸出。
而wfi的全名為wait for interrupt,是系統運行中想要睡下去的時候會呼叫的指令,接受到這道指令後會進入睡眠,等到有interrupt打進來之後才會繼續執行下一道指令,而我們這邊實作上可以先什麼都不做,因為我們可能也不會實作到interrupt功能。
另外,mret是進入ecall之後要回到原本的程式段的時候會呼叫的指令,以前面的例子而言,呼叫printf後我們還是要回到user application繼續執行,這時候呼叫mret可以讓我們回到csr mepc所在的位置,同理sret也會回到csr sepc等位置,因此ecall執行時需要有相應的設定。
最後,fence指令是用來確保前面的指令都完成,這邊由於我們都是一道一道指令完成,在執行下一道指令前前面指令的memory access, 或者是執行皆已完成,因此可以像wfi那樣先什麼都不做。
碎碎念 : 上吐下瀉+發燒,今天內容比較少且沒有實作,希望明天能好一點,不然只能先講buildroot了。